package common

import (
	"context"
	"database/sql/driver"
	"encoding/json"
	"errors"
	"fmt"
	"github.com/goravel/framework/facades"
	"gorm.io/gorm"
	"gorm.io/gorm/clause"
)

type User struct {
	UID                       string      `json:"uid" label:"用户 ID"`
	ShortID                   string      `json:"short_id" label:"短 ID"`
	Nickname                  string      `json:"nickname" label:"昵称"`
	Signature                 string      `json:"signature" label:"个性签名"`
	AvatarLarger              string      `json:"avatar_larger" label:"头像（较大尺寸）"`
	IsVerified                bool        `json:"is_verified" label:"是否已认证"`
	FollowStatus              int         `json:"follow_status" label:"关注状态"`
	AwemeCount                int         `json:"aweme_count" label:"作品数量"`
	FollowingCount            int         `json:"following_count" label:"关注数量"`
	FollowerCount             int         `json:"follower_count" label:"粉丝数量"`
	FavoritingCount           int         `json:"favoriting_count" label:"点赞数量"`
	TotalFavorited            int         `json:"total_favorited" label:"被点赞总数"`
	IsBlock                   bool        `json:"is_block" label:"是否被屏蔽"`
	HideSearch                bool        `json:"hide_search" label:"是否隐藏搜索结果"`
	Constellation             int         `json:"constellation" label:"星座"`
	CreatorTagList            interface{} `json:"creator_tag_list" label:"创作者标签列表"`
	HideLocation              bool        `json:"hide_location" label:"是否隐藏位置"`
	WeiboVerify               string      `json:"weibo_verify" label:"微博认证信息"`
	CustomVerify              string      `json:"custom_verify" label:"自定义认证信息"`
	UniqueID                  string      `json:"unique_id" label:"唯一 ID"`
	PrivateRelationList       interface{} `json:"private_relation_list" label:"私人关系列表"`
	SpecialLock               int         `json:"special_lock" label:"特殊锁定状态"`
	NeedRecommend             int         `json:"need_recommend" label:"是否需要推荐"`
	IsBindedWeibo             bool        `json:"is_binded_weibo" label:"是否绑定微博"`
	WeiboName                 string      `json:"weibo_name" label:"微博用户名"`
	WeiboSchema               string      `json:"weibo_schema" label:"微博模式"`
	WeiboURL                  string      `json:"weibo_url" label:"微博链接"`
	StoryOpen                 bool        `json:"story_open" label:"故事是否开放"`
	StoryCount                int         `json:"story_count" label:"故事数量"`
	HasFacebookToken          bool        `json:"has_facebook_token" label:"是否有 Facebook 令牌"`
	HasTwitterToken           bool        `json:"has_twitter_token" label:"是否有 Twitter 令牌"`
	FbExpireTime              int         `json:"fb_expire_time" label:"Facebook 令牌过期时间"`
	TwExpireTime              int         `json:"tw_expire_time" label:"Twitter 令牌过期时间"`
	HasYoutubeToken           bool        `json:"has_youtube_token" label:"是否有 YouTube 令牌"`
	YoutubeExpireTime         int         `json:"youtube_expire_time" label:"YouTube 令牌过期时间"`
	RoomID                    int         `json:"room_id" label:"房间 ID"`
	LiveVerify                int         `json:"live_verify" label:"直播验证状态"`
	AuthorityStatus           int         `json:"authority_status" label:"权限状态"`
	VerifyInfo                string      `json:"verify_info" label:"认证信息"`
	ShieldFollowNotice        int         `json:"shield_follow_notice" label:"屏蔽关注通知状态"`
	ShieldDiggNotice          int         `json:"shield_digg_notice" label:"屏蔽点赞通知状态"`
	ShieldCommentNotice       int         `json:"shield_comment_notice" label:"屏蔽评论通知状态"`
	BatchUnfollowContainTabs  interface{} `json:"batch_unfollow_contain_tabs" label:"批量取关包含标签"`
	BatchUnfollowRelationDesc interface{} `json:"batch_unfollow_relation_desc" label:"批量取关关系描述"`
	VerificationPermissionIds interface{} `json:"verification_permission_ids" label:"认证权限 ID 列表"`
	WithCommerceEntry         bool        `json:"with_commerce_entry" label:"是否有商业入口"`
}

func (t *User) Scan(value interface{}) error {
	bytesValue, _ := value.([]byte)
	return json.Unmarshal(bytesValue, t)
}

func (t User) Value() (driver.Value, error) {
	return json.Marshal(t)
}

type Param struct {
	Name  string `json:"name"`
	Value string `json:"value"`
}
type Array []string
type Videos []string
type Params []Param
type Keyword []string
type URLList []string

func (t *URLList) Scan(value interface{}) error {
	bytesValue, _ := value.([]byte)
	return json.Unmarshal(bytesValue, t)
}

type Stats struct {
	CommentCount   int `json:"comment_count" label:"评论数量"`
	DiggCount      int `json:"digg_count" label:"点赞数量"`
	DownloadCount  int `json:"download_count" label:"下载数量"`
	PlayCount      int `json:"play_count" label:"播放数量"`
	ShareCount     int `json:"share_count" label:"分享数量"`
	ForwardCount   int `json:"forward_count" label:"转发数量"`
	LiveWatchCount int `json:"live_watch_count" label:"直播观看数量"`
	CollectCount   int `json:"collect_count" label:"收藏数量"`
}

func (t Stats) Value() (driver.Value, error) {
	return json.Marshal(t)
}
func (t *Stats) Scan(value interface{}) error {
	bytesValue, _ := value.([]byte)
	return json.Unmarshal(bytesValue, t)
}

func (t URLList) Value() (driver.Value, error) {
	return json.Marshal(t)
}
func (t *Array) Scan(value interface{}) error {
	bytesValue, _ := value.([]byte)
	return json.Unmarshal(bytesValue, t)
}

func (t Array) Value() (driver.Value, error) {
	return json.Marshal(t)
}
func (t *Params) Scan(value interface{}) error {
	bytesValue, _ := value.([]byte)
	return json.Unmarshal(bytesValue, t)
}

func (t Params) Value() (driver.Value, error) {
	return json.Marshal(t)
}

func (t *Videos) Scan(value interface{}) error {
	bytesValue, _ := value.([]byte)
	return json.Unmarshal(bytesValue, t)
}

func (t Videos) Value() (driver.Value, error) {
	return json.Marshal(t)
}

func (t *Keyword) Scan(value interface{}) error {
	bytesValue, _ := value.([]byte)
	return json.Unmarshal(bytesValue, t)
}

func (t Keyword) Value() (driver.Value, error) {
	return json.Marshal(t)
}

// 地图位置
type Coordinates struct {
	Longitude float64 `json:"longitude"`
	Latitude  float64 `json:"latitude"`
}

type CoordRes struct {
	Type        string    `json:"type"`
	Coordinates []float64 `json:"coordinates"`
}

func (c CoordRes) GormDataType() string {
	return "geometry"
}

// GormValue 根据坐标数据生成 SQL 表达式
func (c CoordRes) GormValue(ctx context.Context, db *gorm.DB) clause.Expr {
	//如果c为nil,返回nil
	if c.Coordinates == nil {
		//赋值为nil
		return clause.Expr{SQL: "NULL", Vars: []interface{}{}}
	}

	// 生成 SQL 表达式
	return clause.Expr{
		SQL:  "ST_GeomFromText(?,4326)",
		Vars: []interface{}{fmt.Sprintf("POINT(%f %f)", c.Coordinates[1], c.Coordinates[0])},
	}
}

// Scan 方法实现了 sql.Scanner 接口，用于从数据库中扫描和解码坐标数据
func (c *CoordRes) Scan(value interface{}) error {
	if value == nil {
		return nil
	}
	bytes, ok := value.([]byte)
	if !ok {
		return errors.New("invalid value type, expected []byte")
	}
	if len(bytes) == 0 {
		c = nil
		return nil
	}
	var coordRes string
	querySql := "SELECT ST_AsGeoJSON(?) as coord"
	param := string(bytes)
	facades.Orm().Query().Raw(querySql, param).Pluck("coord", &coordRes)
	err := json.Unmarshal([]byte(coordRes), c)
	return err
}
